render hooks パターン
状態とコンポーネントを両方渡す時に便利
↑のLINE証券の記事でuhyo氏がこのパターンを命名してくれたおかげで、ググりやすくなった
これ以前でも、hooksからelement返すのはやったことある人は多分いると思うから起源は分からん
起源は追わなくてもいいかなと思う
命名してくれたことが偉いと思う
code:ts
const App: React.FC = () => {
return (
<div>
{node}
<p>
<button disabled={!isAllChecked}>次へ</button>
</p>
</div>
)
}
モーダルの実装なんかも
code:js
const App: React.FC = () => {
const {isOpen, open , node} = useModal()
return (
<div>
{node}
<button onClick={open}>開く</button>
</div>
)
}
twitterで検索すると、このパターンに対して不安を感じる声がある
hooksは単なる関数であり、ReactElementは単なるJSのオブジェクトに過ぎないので何も問題ない
不安を覚えるなら、そもそもJavaScriptでUIを構築することに不安を覚えても良いのでは?
hooksライブラリからコンポーネントを返したいことはあんまりないので、ライブラリにて採用されてる実例は少ない
このパターンを利用すべきケースは、ライブラリじゃなくてアプリケーション側のほうが発生しやすいと思われる
Element(ReactNode)を返すべきかFC ( ()=>Element)を返すべきか
@uhyo_: 「hooksからコンポーネントを返す」と言われたときにReact.FCを返すやつとJSX.Elementを返すやつが混同されている懸念がある。ぼくが推してるのはJSX.Elementを返すほうです(?) @uhyo_: React.FCを返すほうはあまり良くないと思う。というのもステートを内包させると必然的にステートが変わると別の関数オブジェクトになり、再レンダリング時にパフォーマンスのペナルティがあるから🫐 たしかにmiyamonz.icon
でもLINE証券の記事では後者なんだな
Element直返しで良いと思ってるが、何か後から渡す引数があるなら、(arg)=>Elementでもいいだろう
この記事にもあるように、結局FC(関数)を渡せば、それはobjectの同一性においてレンダリングのたびに異なるelementが作られうるので、基本はelementを返すのが正しい
ここで紹介されてるreact-hooks-use-modalもこのパターンと言える
こっちはFCを返してる
@uhyo_: そうだな。childrenは特殊な構文を与えられたrender propsであると考えたほうが幸せになりそう。レイアウトの責務を持つコンポーネントだとslotが1つだと普通に足りないときがあるし(?) そのとおりすぎて、childrenがReactNodeなのだから、別のpropにわたす変数もReactNode(Element)で保持して良いに決まってるmiyamonz.icon
そもそも、react elementを普段遣いのオブジェクトとして触りつつ、それを関数で返すようになると勝手にrender hooksになる
ただし厳密には、内部にuseState, useEffectなどが無いようなものは、hooksでは無く単なる関数で
コンポーネントレンダリング時にif文で分岐させてはいけない系の制約もなくなる
記事
fileのinput要素と、渡されたdataURLを返す
useStateのsetをコンポーネントとして受け取ると考えるとたしかにこれは良いか
値をユーザから受け取って、必要な情報を取り出すというロジックをrender hooks内に閉じ込められる、と考えられる
さらに、プレビュー画面もコンポーネントにしてしまうのも書いている
良く考えたらそりゃそうだなmiyamonz.icon
しかし、これが当たり前、と言えるのはReactをある程度習熟してないとむずそうだな
あまり海外の文献は見当たらない